package com.example.demo;

// RSAwithSHA256

import cn.hutool.core.io.FileUtil;
import com.google.gson.JsonObject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.PSSParameterSpec;
import java.util.Base64;

public class RSA_Sign {
    public static String getSignature(JsonObject ctx, JsonObject req) {
        String signatureBase64 = null;
        // 开发者本地信息
        String local_appid = ctx.get("local_appid").getAsString();
        String url_path = ctx.get("url_path").getAsString();
        String local_sym_sn = ctx.get("local_sym_sn").getAsString();
        String local_private_key = ctx.get("local_private_key").getAsString();
        local_private_key = FileUtil.readString(new File("e:\\ai\\锦鲤私钥.txt"), "utf-8");
        // 待请求API数据
        long reqTs = req.get("req_ts").getAsLong();
        String reqData = req.get("req_data").getAsString();

        String payload = url_path + "\n" + local_appid + "\n" + reqTs + "\n" + reqData;
        byte[] dataBuffer = payload.getBytes(StandardCharsets.UTF_8);
        try {
            local_private_key = local_private_key.replace("-----BEGIN RSA PRIVATE KEY-----", "");
            local_private_key = local_private_key.replace("-----END RSA PRIVATE KEY-----", "");
            local_private_key = local_private_key.replaceAll("\\s+", "");

            byte[] decoded = Base64.getDecoder().decode(local_private_key);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);

            KeyFactory rsa = KeyFactory.getInstance("RSA");
            System.out.println("rsa = " + rsa);

            RSAPrivateKey priKey = (RSAPrivateKey) rsa.generatePrivate(keySpec);
            Signature signature = Signature.getInstance("RSASSA-PSS");
            // salt长度，需与SHA256结果长度(32)一致
            PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
            signature.setParameter(pssParameterSpec);
            signature.initSign(priKey);
            signature.update(dataBuffer);
            byte[] sigBuffer = signature.sign();
            signatureBase64 = Base64.getEncoder().encodeToString(sigBuffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return signatureBase64;
        /*
        最终请求头字段
        {
            "Wechatmp-Appid": local_appid,
            "Wechatmp-TimeStamp": req_ts,
            "Wechatmp-Signature": sig,
        }
        */
    }

    private static JsonObject getReq() {
        JsonObject req = new JsonObject();
        req.addProperty("req_ts", 1635927954);
        req.addProperty("req_data", "{\"iv\":\"fmW/zNxXlytUZBgj\",\"data\":\"0IDVdrPtSPF/Oe2CTXCV2vVNPbVJdJlP2WaTMQnoYLh5iCrrSNfQFh25EnStDMf0hLlVNBCZQtf9NaV0m4aRA4AAYIO7oR/Ge+4yY4EmZp5EVPB42xjScgMx5X3D4VdLCfynXIUKUtZHZvk1zmLVE3RauzJgiM1BB1CPmwcENo3MTJ0z8Vfkf5tMv54kOXobDLlV5rfqKdAX7gM/rP82DgZdt9vvZX44ipdbHIjJvw83ZXAFtvftdVw2Qd8=\",\"authtag\":\"5qeM/2vZv+6KtScN94IpMg==\"}");
        return req;
    }

    private static JsonObject getCtx() {
        JsonObject ctx = new JsonObject();
        // 仅做演示，敏感信息请勿硬编码
        String localPrivateKey = "-----BEGIN PRIVATE KEY-----\n" +
                "MIIEpAIBAAKCAQEA9gf9gshdR9AQzX0ghoC8NO7QY1/+y/mgf8zDaufOQRnEfn6u\n" +
                "fLQ1YfMkLaez1jPmFZ3BqmKGKyP0DUiETZz0o5W4XoIhuyZa3J5U3BpyOhW2O7HQ\n" +
                "YcP52ZaGkOpylAG4yck3dGorbzQgYnwHfgYDIzUsFbz4AKoAyaVfZCFB0KpDZ51Y\n" +
                "dka02Wvrp5pp9K9ZV4xSNvk08PR8Da6dcHR+1b0NLgqLD7t/3Tujcxc4SMIf4QSq\n" +
                "khKdsHyaPY2zHKuOsJb8KxK2Lxd1C7rToTIDxQjU6rK3LZ7XvbgPpBhi/mrmDxfE\n" +
                "Qmp0GnE88tWP5XYuK/3HP/3stu+IAmcTRMVtZwIDAQABAoIBACIbF3SSzAORf1LN\n" +
                "Hr4miHCaDn9IJm0mTK6KtyhRvBDgPpH+g7e7z46lgwVlMxPlm+axONCi2dCPKlzR\n" +
                "Ca4srOkkbyuCxKRJ+9yLgl4EuIL+0YVS7/0tiqw0JrFeHsYPuwsV/r7/nMfMpRSh\n" +
                "9vPsZ3DxBQx6ZrLI3lUVvLSHu7TuL9YzDCUKAZSwf2Ti5ftdoTR8LJUfUqUGYYPY\n" +
                "rE+ViOhdalDhsYIE65RYDnAYJ1FPHtpHCMg06IsfC4N9OINTVql9nmR7uCs28tAn\n" +
                "GI7lemaaJIFLmk+h//+VN2XGjr4vGhuN4JSSlPokGXwn7b+/ITFPI+pRctyPDJz6\n" +
                "UkxbL3kCgYEA/ZzgXOG3YPRmqC1abORYeFm0ZhL6iHHBVjCn0+GSg0061ixf/3ZM\n" +
                "Zi0QqXUrOQjO4Esv0wwhTgg9sStVSVhibB+AQJ7uBOGDmtvS8RgtqXZCG/IT7NXx\n" +
                "JPwA1O3aic5UUEvoevmE2olV5hYz9Wwbv9L6a2CYEIuM1hBR8ut+jS0CgYEA+FjY\n" +
                "P+kIwj/dgGqaTcJTFj7P3Iy1Rp9ZvKrV6/TkgTbITadMTlkI0wmk8Dzpcwy1rJiR\n" +
                "YZ5MIwzTZGu44MbMOIz3g6q96GvzUdRULqxaAagO2yOeCmnRC1U5IcY4T5J9xAp5\n" +
                "7UUWliMKRhaqvGG3DgzPQDeAUH1GM7S9e+i/SWMCgYEAu860h5PPTMkwTFJpqEHh\n" +
                "Eh677OsZBHnZBo65ebqN2RYUAA6UeIWORgwRTqwp+e5/5LFJFSzibPrFVLIWUl5V\n" +
                "ZGRfgXswIAUwhDlNmKSjC987TZ6TCsvT6+OCaixJrctRvLS50Hd+3qbdKao/h/sr\n" +
                "AX6nW2UItxfgj5U+WnnyGXECgYEAlxWFyau9ll9AI+W2peO4pGnmDujTR3meIDdW\n" +
                "GUxMz4dCaGuE8o0b3zeYzkZgR4vN4oiWuWqSKyicWhVmzehjSWwJEGMJUaKKzpd7\n" +
                "90EHKMbS8uJCPVeOw3Q/Y5qxm0cll+Q/tOc5DHGYyHb1u9E+ih+k3g5l05HC6aXl\n" +
                "OMKpzL0CgYBUdJXrQFJf6UbQFrrAn3Xue6n4il/tG9bW7FWMN354LTVojnccNT5Z\n" +
                "YosI4khUHtguKbCzob8OMpEM/vSj4z2AfTqQ2Sr5jnEYlfFLwpsmBvCIfyyf8Z/d\n" +
                "/yrn0ZlgpoWoGFSURiRwC6NcqDsOIXW7tyaagC/De8py2HzcMvL+QA==\n" +
                "-----END PRIVATE KEY-----\n";
        ctx.addProperty("local_private_key", localPrivateKey);
        ctx.addProperty("local_sym_sn", "196191734ad1c55582e27bfde89a0cf4");
        ctx.addProperty("local_appid", "wxdbcd09b92810a1f9");
        ctx.addProperty("url_path", "https://api.weixin.qq.com/wxa/getuserriskrank");
        return ctx;
    }

    public static void main(String[] args) {
        JsonObject req = getReq();
        JsonObject ctx = getCtx();
        String res = getSignature(ctx, req);
        System.out.println(res);

    }
}
